<?php
require_once 'WxPay.Config.php';
require_once 'WxPay.Data.php';

class WxPayNotify
{
    // 接收并处理微信支付异步通知
    public function Handle($needSign = true)
    {
        $xml = file_get_contents('php://input');
        if (!$xml) {
            $this->ReplyNotify(false, "获取通知数据失败");
            return false;
        }

        try {
            $data = WxPayResults::Init($xml);
        } catch (WxPayException $e) {
            $this->ReplyNotify(false, $e->errorMessage());
            return false;
        }

        if ($needSign && !$this->CheckSign($data)) {
            $this->ReplyNotify(false, "签名验证失败");
            return false;
        }

        if ($this->ProcessNotify($data)) {
            $this->ReplyNotify(true, "OK");
            return true;
        } else {
            $this->ReplyNotify(false, "处理通知失败");
            return false;
        }
    }

    // 检查签名
    private function CheckSign($data)
    {
        $sign = $data['sign'];
        unset($data['sign']);
        $input = new WxPayDataBase();
        foreach ($data as $key => $val) {
            $input->Set($key, $val);
        }
        return $input->MakeSign() === $sign;
    }

    // 处理通知的具体逻辑，需要在子类中重写
    public function ProcessNotify($data)
    {
        return false;
    }

    // 回复微信支付通知
    private function ReplyNotify($success, $msg)
    {
        $data = new WxPayDataBase();
        if ($success) {
            $data->Set('return_code', 'SUCCESS');
            $data->Set('return_msg', 'OK');
        } else {
            $data->Set('return_code', 'FAIL');
            $data->Set('return_msg', $msg);
        }
        echo $data->ToXml();
    }
}

// 示例子类，可根据实际业务需求重写 ProcessNotify 方法
class MyWxPayNotify extends WxPayNotify
{
    public function ProcessNotify($data)
    {
        if ($data['return_code'] === 'SUCCESS' && $data['result_code'] === 'SUCCESS') {
            // 这里可以添加你的业务逻辑，比如更新订单状态等
            $out_trade_no = $data['out_trade_no'];
            // 示例：记录日志
            file_put_contents('wxpay_notify.log', "支付成功，订单号：$out_trade_no\n", FILE_APPEND);
            return true;
        }
        return false;
    }
}    